import matplotlib.pyplot as plt
import torch

# =================== 曲线图 =========================
x = torch.linspace(0, 1, 20)  # (20,)
y = x ** 2

plt.plot(x, y, 'ro')


# =================== 激活函数 =========================
# sigmoid函数
def sigmoid(x):
    return 1 / (1 + torch.exp(-x))


# =================== 预测线 =========================
# 预测的w,b
w = torch.tensor(0.1, requires_grad=True)  # w需要求导
b = torch.tensor(0.1, requires_grad=True)  # b需要求导
# 预测的 predict_y

predict_y = sigmoid(w * x + b)  # 直线不可以拟合曲线的情况
# .detach() 对原本数据进行备份 numpy() 将torch的值转化为numpy
line, = plt.plot(x.detach().numpy(), predict_y.detach().numpy(), 'b--')
# 用循环改变w的值
for i in range(10000):
    predict_y = sigmoid(w * x + b)
    # 输出总的距离大小
    e = torch.sum((predict_y - y) ** 2)
    e.backward()
    with torch.no_grad():  # 官方要求在进行w，b值变化时，不可以进行求导
        # 更新w的值: 加入激活函数之后求导变得异常困难，该怎么办？
        w -= w.grad * 0.1
        # 更新b的值
        b -= b.grad * 0.1
        # 对w，b的斜率值缓存进行清空
        w.grad.zero_()
        b.grad.zero_()
    line.set_data(x.detach().numpy(), predict_y.detach().numpy())
    plt.pause(0.1)
